package me.zhengjie.modules.fund.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.modules.fund.domain.FundNetValue;
import me.zhengjie.modules.fund.repository.FundNetValueRepository;
import me.zhengjie.modules.fund.reptile.FundCrawler;
import me.zhengjie.modules.fund.service.FundNetValueService;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.text.ParseException;
import java.util.List;
import java.util.Objects;

@Slf4j
@Service
public class FundNetValueServiceImpl implements FundNetValueService {

    @Resource
    private FundNetValueRepository fundNetValueRepository;

    @Resource
    private FundCrawler fundCrawler;

    /**
     * @param code
     * @return
     * @see FundNetValueService#findNewestByCode(String)
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public FundNetValue findNewestByCode(String code) throws ParseException {

        FundNetValue fundNetValue = fundNetValueRepository.findFirstByCodeOrderByDateDesc(code);
        if (Objects.isNull(fundNetValue)) {
            // 当年数据初始化
            initFundNetValue(code);

            // 获取最新数据
            List<FundNetValue> latestNetValues = fundCrawler.getLatestNetValues(code);
            if (!CollectionUtils.isEmpty(latestNetValues)) {
//                fundNetValueRepository.saveAll(latestNetValues);
                fundNetValue = latestNetValues.get(0);
            }
        }
        return fundNetValue;
    }

    private void initFundNetValue(String code) throws ParseException {
        int page = 1;
        List<FundNetValue> fundNetValues;
        do {
            fundNetValues = fundCrawler.findFundNetValueByPage(code, PageRequest.of(page, 20), null);
            if (CollectionUtils.isEmpty(fundNetValues)) {
                break;
            }
            fundNetValueRepository.saveAll(fundNetValues);
            page++;
        } while (!CollectionUtil.isEmpty(fundNetValues));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveAll(List<FundNetValue> fundNetValues) {
        for (FundNetValue fundNetValue : fundNetValues) {
            FundNetValue netValueItem = fundNetValueRepository.findByCodeAndDate(fundNetValue.getCode(), fundNetValue.getDate());
            if (Objects.isNull(netValueItem)) {
                fundNetValueRepository.save(fundNetValue);
            }
        }
    }

    @Override
    public FundNetValue findNetValueByCodeOrderByDateDesc(String code) {
        return fundNetValueRepository.findFirstByCodeOrderByDateDesc(code);
    }
}
